package com.cv.framework.security.core.aop;

import com.cv.framework.common.exception.constants.GlobalErrorCodeConstants;
import com.cv.framework.security.core.annotations.WithoutPreAuthenticated;
import com.cv.framework.security.core.utils.SecurityFrameworkUtil;
import com.cv.system.api.token.form.LoginUser;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;

import javax.annotation.security.PermitAll;
import java.lang.reflect.Method;

import static com.cv.framework.common.exception.utils.ServiceExceptionUtil.exception0;

/**
 * 预授权切面，用于拦截未登录的用户
 *
 * @author Charles_XDXD
 */
@Aspect
@Slf4j
@Order(1) // 设置优先级，保证先执行
public class PreAuthenticatedAspect {

    @Around("within(com.cv..*.controller..*) && execution(* *(..))")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();

        if (method.isAnnotationPresent(WithoutPreAuthenticated.class)
                || method.isAnnotationPresent(PermitAll.class)) {
            return joinPoint.proceed();
        }

        LoginUser loginUser = SecurityFrameworkUtil.getLoginUser();

        if (loginUser == null || loginUser.getId() == null) {
            throw exception0(GlobalErrorCodeConstants.UNAUTHORIZED.getCode(), "账号未登录或访问令牌已过期！");
        }

        return joinPoint.proceed();
    }

}
